﻿using System;
using System.Collections.Generic;
using Tavis.Interfaces;

namespace Tavis {
    public class LinkFactory : ILinkFactory {
        private readonly IDictionary<Type, string> _RelLookup = new Dictionary<Type, string>();
        private readonly IDictionary<string, Type> _LinkTypes = new Dictionary<string, Type>();
		private readonly List<Func<ILink, ILink>> _LinkProcessors = new List<Func<ILink, ILink>>();



		public ILink CreateLink(string linkRelation) {
            ILink link;
            if ((linkRelation != null) && (_LinkTypes.Keys.Contains(linkRelation))) {
                link = (ILink)Activator.CreateInstance(_LinkTypes[linkRelation]);
            } else {
                link = new Link { Relation = linkRelation };
            }

			foreach (var processor in _LinkProcessors) {
				link = processor(link);
			}

            return link;
        }

        public string GetRel(Type type) {
            return _RelLookup[type];
        }

        public void RegisterLinkType<T>(string relation) where T : ILink {
			var type = typeof(T);

			if (_RelLookup.ContainsKey(type)) {
				throw new ArgumentException("Cannot register two relations to same type");
				// Because HypermediaContent caches links based on a rel reversed-looked-up from the type
			}

            _LinkTypes.Add(relation, type);
            _RelLookup.Add(type, relation);
        }


    	public void RegisterLinkProcessor(Func<ILink, ILink> processor)
    	{
			_LinkProcessors.Add(processor);
    	}
    }
}
